home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1995 June: Reference Library / Dev.CD Jun 95 / Dev.CD Jun 95.toast / What's New? / New System Software Extensions / QuickDraw 3D ß / Programming / SampleCode / Modeller ƒ / Modeller_file.c < prev    next >
Encoding:
Text File  |  1995-03-31  |  12.5 KB  |  593 lines  |  [TEXT/MPS ]

  1. //        file.c
  2. //
  3. //        File Input/Output routines.
  4. //        
  5. //
  6. //        Author:        Rob Johnston
  7. //        Date:        Thursday, January 26, 1992
  8. //
  9. //    Modification History:
  10. //
  11. //        11/27/94    nick        there seems to be a problem reading metafiles into the app
  12. //        01/25/95    nick        slotted in spin code (thanks kent), updated for viewhints.  
  13. //                                If we have view hints, then we can export things like the 
  14. //                                renderer type and lighting and camera in a drag or cut/copy
  15. //
  16. //
  17. //    To Do:
  18. //         factor for AppleEvents
  19. //
  20. //        Copyright © 1992-94 Apple Computer, Inc., All Rights Reserved
  21.  
  22. #include "Modeller_globals.h"
  23. #include "Modeller_prototypes.h"
  24. #include "Modeller_resources.h"
  25.  
  26. #include "QD3DStorage.h"
  27. #include "QD3DGroup.h"
  28. #include "QD3DIO.h"
  29. #include "QD3DShader.h"
  30. #include "QD3DView.h"
  31.  
  32. #include "Modeller_errors.h"
  33. #include "Modeller_file.h"
  34. #include "Modeller_camera.h"
  35. #include "Modeller_document.h"
  36. #include "Modeller_PICTImport.h"
  37.  
  38.  
  39. #include <string.h>
  40.  
  41. static short  ReadDocumentFile(DocumentPtr theDocument, TQ3Boolean isText);
  42. static PicHandle OpenPICTFile(FSSpec *theFile);
  43. static OSErr WriteDocumentFile(DocumentPtr theDocument);
  44. //-----------------------------------------------------------------------------
  45.  
  46. TQ3Status Modeller_ReadScene(
  47.     TQ3FileObject        file,
  48.     short                isText,
  49.     TQ3SharedObject        *viewHints,
  50.     TQ3Object            *model)
  51. {
  52.     char                filename[64];
  53. //    TQ3Object            group;
  54.     TQ3Object            object;
  55.     TQ3Boolean            isEOF;
  56.     
  57.     *viewHints    = NULL;
  58.     if( *model ) {
  59.         Q3Object_Dispose(*model);
  60.     }
  61.  
  62.     *model        = Q3DisplayGroup_New();
  63.  
  64. //    group        = NULL;
  65.     object        = NULL;
  66.     
  67.     SetCursor(*GetCursor(watchCursor));
  68.  
  69.     if (Q3File_OpenRead(file, NULL) != kQ3Success)
  70.     {
  71.         SetCursor(&qd.arrow);
  72.         return kQ3Failure;
  73.     }
  74.  
  75.     if (Q3File_IsEndOfFile(file, &isEOF) != kQ3Success) 
  76.     {
  77.         SetCursor(&qd.arrow);
  78.         return kQ3Failure;
  79.     }
  80.     
  81.     while (isEOF == kQ3False)
  82.     {
  83.         object = NULL;
  84.         
  85.         if (Q3File_ReadObject(file, &object) == kQ3Failure) 
  86.         {
  87.             break;
  88.         }
  89.         if (Q3File_IsEndOfFile(file, &isEOF) != kQ3Success) 
  90.         {
  91.             break;
  92.         }
  93.         if (isEOF == kQ3True)
  94.         {
  95.             if (object == NULL) 
  96.                 break;
  97.         }
  98.         
  99.         if (object == NULL)
  100.             continue;
  101.         
  102.         if (Q3Object_IsType(object, kQ3SharedTypeViewHints))
  103.         {
  104.             if (*viewHints == NULL)
  105.             {
  106.                 *viewHints = object;
  107.                 object = NULL;
  108.             }
  109.         }
  110.         else if (Q3Object_IsDrawable(object))
  111.         {
  112.             if (*model)
  113.             {
  114.                 Q3Group_AddObject(*model, object);
  115.             }
  116. //            else
  117. //            {
  118. //                group = Q3DisplayGroup_New();
  119. //
  120. //                Q3Group_AddObject(group, *model);
  121. //                Q3Group_AddObject(group, object);
  122. //                Q3Object_Dispose(*model);
  123. //
  124. //                *model = group;
  125. //            }
  126.         }
  127.         if (object != NULL) 
  128.             Q3Object_Dispose(object);
  129.     }
  130.             
  131.     Q3File_Close(file);
  132.     
  133.     if (isEOF == kQ3False)
  134.     {
  135.         if (*model != NULL)
  136.         {    Q3Object_Dispose(*model); *model = NULL; }
  137.     
  138.         if (*viewHints != NULL)
  139.         {    Q3Object_Dispose(*viewHints); *viewHints = NULL; }
  140.         
  141.         SetCursor(&qd.arrow);
  142.         return kQ3Failure;
  143.     }
  144.     
  145.     SetCursor(&qd.arrow);
  146.     return kQ3Success;
  147. }
  148.  
  149. //-----------------------------------------------------------------------------
  150. //
  151. //    Modeller_WriteScene()
  152. //
  153.  
  154. void Modeller_WriteScene(
  155.     TQ3FileObject        file,
  156.     short                textMode,
  157.     DocumentPtr            theDocument)
  158. {
  159.     TQ3GroupPosition    gPos;
  160.     TQ3Object            object;
  161.     TQ3ViewStatus        fileStatus;
  162.     
  163.     SetCursor(*GetCursor(watchCursor));
  164.  
  165.     if (Q3File_OpenWrite(file, (textMode ? kQ3FileModeText : 0)) != kQ3Success)
  166.     {
  167.         SetCursor(&qd.arrow);
  168.         return;
  169.     }
  170.     
  171.     Q3View_StartWriting(theDocument->theView, file);
  172.         
  173.     if (theDocument->viewHints != NULL)
  174.     {
  175.         if (Q3Object_Submit(theDocument->viewHints, theDocument->theView) == kQ3Failure)
  176.         {
  177.             Q3File_Cancel(file);
  178.             SetCursor(&qd.arrow);
  179.             return;
  180.         }
  181.     }
  182.     do {
  183.         if (theDocument->documentGroup != NULL)
  184.         {
  185.                 Q3Group_GetFirstPosition(theDocument->documentGroup, &gPos);
  186.                 while (gPos)
  187.                 {
  188.                     TQ3Status status;
  189.                     
  190.                     Q3Group_GetPositionObject(theDocument->documentGroup, gPos, &object);
  191.                     status = Q3Object_Submit(object, theDocument->theView);
  192.                     Q3Object_Dispose(object);
  193.                     
  194.                     if (status != kQ3Failure)
  195.                     {
  196.                         Q3Group_GetNextPosition(theDocument->documentGroup, &gPos);
  197.                     }
  198.                 }
  199.         }
  200.     } while ((fileStatus = Q3View_EndWriting(theDocument->theView)) == kQ3ViewStatusRetraverse);
  201.         
  202.     if( Q3File_Close(file) == kQ3Failure ) {
  203.         SetCursor(&qd.arrow);
  204.         return;
  205.     }
  206.     SetCursor(&qd.arrow);
  207.     return ;
  208. }
  209.  
  210.  
  211. //-----------------------------------------------------------------------------
  212. // ReadDocumentFile
  213.  
  214. short ReadDocumentFile(DocumentPtr theDocument, TQ3Boolean isText)
  215. {
  216.     TQ3StorageObject        storage;
  217.     TQ3FileObject        fd;
  218.     TQ3Object             objects = nil;
  219.     TQ3Object            viewHints;    
  220.     
  221.     storage = Q3MacintoshStorage_New( theDocument->fRefNum );
  222.     
  223.     if (storage == nil)
  224.         goto bail;
  225.     
  226.     fd = Q3File_New();
  227.     
  228.     if (fd == nil)
  229.         goto bail;
  230.  
  231.     Q3File_SetStorage(fd, storage);
  232.     Q3Object_Dispose(storage);
  233.     
  234.     Modeller_ReadScene(
  235.         fd,
  236.         isText,
  237.         &viewHints,
  238.         &theDocument->documentGroup) ;
  239.     
  240.     ModellerDocument_UpdateView( theDocument, viewHints ) ;
  241.     
  242.     AdjustLightsPositions(theDocument);
  243.  
  244.     if (viewHints)
  245.         Q3Object_Dispose(viewHints);
  246.  
  247.     Q3Object_Dispose(fd);
  248.  
  249.     return(noErr);
  250. bail:
  251.     Q3Object_Dispose(fd);
  252.  
  253.     return(fnOpnErr);
  254. }
  255.  
  256. //-
  257.  
  258. PicHandle OpenPICTFile(
  259.     FSSpec *theFile)
  260. {
  261.     OSErr        err;
  262.     long        curEOF;
  263.     PicHandle    my_pic;
  264.     long         count;
  265.     Ptr         buffer;
  266.     short        refNum;
  267.     
  268.     if (FSpOpenDF(theFile, fsRdWrPerm, &refNum))
  269.         return(0);
  270.  
  271.     /* get size of file */
  272.     err = GetEOF(refNum, &curEOF);
  273.     if (err != 0) {
  274.         return(0);
  275.     }
  276.     
  277.     /* move the file mark to 512 */
  278.     err = SetFPos(refNum, fsFromStart, 512L);
  279.     if (err != 0) {
  280.         return(0);
  281.     }
  282.  
  283.     /* size of data to read */
  284.     count = curEOF - 512;
  285.     
  286.     /* create the PicHandle */
  287.     my_pic = (PicHandle)NewHandle(count);
  288.     HLock((Handle)my_pic);
  289.     
  290.     /* read the PICT info */
  291.     buffer = (Ptr)(*my_pic);
  292.     err = FSRead(refNum, &count, buffer);
  293.     if (err != 0) {
  294.         return(0);
  295.     }
  296.     HUnlock((Handle)my_pic);
  297.  
  298.     FSClose(refNum);
  299.     
  300.     return (my_pic);
  301. }
  302.  
  303.  
  304.  
  305. OSErr WriteDocumentFile(DocumentPtr theDocument)
  306. {
  307.     OSErr        theResult;
  308.     long        length;
  309.     char        *bufPtr;
  310.  
  311.     SetCursor(*GetCursor(watchCursor));
  312.  
  313.     if (! theDocument->fRefNum)
  314.         return(fnOpnErr);
  315.  
  316.     if ((theResult = SetFPos(theDocument->fRefNum, fsFromStart, 0)) != noErr ) 
  317.         return(theResult);
  318.  
  319.     if( theDocument->documentGroup ) {
  320.         TQ3StorageObject    storage;
  321.         TQ3FileObject    fd;
  322.         
  323.         storage = Q3MacintoshStorage_New(theDocument->fRefNum);
  324.         
  325.         if (storage == nil)
  326.             goto bail;
  327.         
  328.         fd = Q3File_New();
  329.         
  330.         if (fd == nil)
  331.             goto bail;
  332.  
  333.         Q3File_SetStorage(fd, storage);
  334.         Q3Object_Dispose(storage);
  335.         
  336.         Modeller_WriteScene(fd, 
  337.                             kQ3FileModeText,
  338.                             theDocument) ;
  339.  
  340.         Q3Object_Dispose(fd);
  341.     }
  342.     return(noErr);
  343. bail:
  344.     return(fnOpnErr);
  345. }
  346.  
  347.  
  348. void DoNewDocument(void)
  349.  
  350. {    DocumentPtr theDocument;
  351.  
  352.     if ((theDocument = NewDocument(NULL, NULL)) != nil) {
  353.         ShowWindow(theDocument->theWindow);
  354.     }
  355. }
  356.  
  357. OSErr DoOpenFile(FSSpec *theFile)
  358.  
  359. {    OSErr                result;
  360.     short                refNum;
  361.     DocumentPtr         theDocument;
  362.     FInfo                fndrInfo ;
  363.     TQ3Boolean            isText ;
  364.  
  365.     // we assume the FSSpec passed in was valid, get the file information
  366.     // we need to know the file type, this routine may get called by an appleEvent
  367.     // handler, so we can't assume a type, we need to get it from the fsspec.
  368.     
  369.     FSpGetFInfo( theFile, &fndrInfo ) ;
  370.     
  371.     // pull out the file type
  372.     
  373.     isText = (fndrInfo.fdType == 'TEXT') ;
  374.     
  375.     if ((result = FSpOpenDF(theFile, fsRdWrPerm, &refNum)) != noErr)
  376.         return(result);
  377.  
  378.     if ((theDocument = NewDocument(NULL, NULL)) != nil) {
  379.         theDocument->fRefNum = refNum;
  380.         theDocument->theFileSpec = *theFile ;
  381.         SetCursor(*GetCursor(watchCursor));
  382.         ReadDocumentFile( theDocument, isText ) ;
  383.         SetWTitle(theDocument->theWindow, theFile->name);
  384.         ShowWindow(theDocument->theWindow);
  385.         AdjustCamera(theDocument,
  386.             theDocument->theWindow->portRect.right - theDocument->theWindow->portRect.left,
  387.             theDocument->theWindow->portRect.bottom - theDocument->theWindow->portRect.top);
  388.         SetCursor(&qd.arrow);
  389.  
  390.     } else {
  391.         SysBeep(1);
  392.         FSClose(refNum);
  393.         return(memFullErr);
  394.     }
  395.     return(noErr);
  396. }
  397.  
  398.  
  399.  
  400. void DoOpenDocument(DocumentPtr theDocument)
  401. {    short                refNum;
  402.     SFTypeList            theTypeList = { 'TEXT', '3DMF', 'PICT', nil };
  403.     StandardFileReply    theReply;
  404.  
  405.     StandardGetFile(0L, 3, theTypeList, &theReply);
  406.  
  407. #ifndef PODIUM_APP
  408.  
  409.     // read for modeller files
  410.     if (theReply.sfGood) {
  411.         if( theReply.sfType == 'TEXT' || theReply.sfType == '3DMF') {
  412.             DoOpenFile(&theReply.sfFile);
  413.         } else if( theReply.sfType == 'PICT' && theDocument && theDocument->documentGroup) {
  414.             PicHandle            thePict;
  415.             TQ3StoragePixmap     textureImage;
  416.             
  417.             // get the picture from the file
  418.             thePict = OpenPICTFile(&theReply.sfFile);
  419.             
  420.             // make a texture
  421.             TextureFromPICT( thePict, &textureImage);
  422.             AddTextureToDocument( theDocument, &textureImage);
  423.             
  424.             // and free the space occupied by the picture
  425.             KillPicture(thePict) ;
  426.         
  427.         }
  428.     }
  429. #else
  430.  
  431.     // read for podium files
  432.     if (theReply.sfGood) {
  433.         // podium's slide files are PICT files
  434.         if( theReply.sfType == 'PICT' ) {
  435.  
  436.             short            refNum;
  437.             DocumentPtr        theDocument;
  438.             PicHandle        theBackgroundPict ;
  439.             OSErr            theErr ;
  440.             
  441.             if((theErr = FSpOpenDF(&theReply.sfFile, fsRdPerm, &refNum)) != noErr )
  442.                 return ;
  443.         
  444.             if ((theDocument = NewDocument(NULL, NULL)) != nil) {
  445.                 Rect            bounds;
  446.                 PicHandle        thePict;
  447.                 GWorldPtr        savedGWorld ;
  448.                 GDHandle        savedDevice ;
  449.                 
  450.                 GetGWorld(&savedGWorld,&savedDevice);
  451.                 
  452.                 theBackgroundPict = OpenPICTFile(&theReply.sfFile);
  453.                 bounds = (**theBackgroundPict).picFrame;
  454.  
  455.                 theErr = UpdateGWorld(&theDocument->screenBuffer, 16, &bounds, nil, nil, 0L ) ;
  456.                 if( (theErr = UpdateGWorld(&theDocument->bgOffscreen, 16, &bounds, nil, nil, 0L )) != noErr )  {
  457.                     return ;
  458.                 }
  459.                 
  460.                 // draw the picture into the offscreen    
  461.                 SetGWorld( theDocument->bgOffscreen , nil ) ;
  462.                 DrawPicture( theBackgroundPict, &bounds ) ;
  463.                 SetGWorld(savedGWorld,savedDevice);
  464.                 
  465.                 SizeWindow(theDocument->theWindow, bounds.right - bounds.left, bounds.bottom - bounds.top, false);
  466.                 SetWTitle(theDocument->theWindow, theReply.sfFile.name);
  467.                 ShowWindow(theDocument->theWindow) ;
  468.  
  469.             } else {
  470.             
  471.                 SysBeep(1);
  472.                 FSClose(refNum);
  473.                 return;
  474.                 
  475.             }
  476.         }
  477.         else if(theDocument != nil && (theReply.sfType == 'TEXT' || theReply.sfType == '3DMF')) {
  478.  
  479.             // did we try to open a metafile ???
  480.         
  481.             OSErr                result;
  482.             short                refNum;
  483.             DocumentPtr         theDocument;
  484.             FInfo                fndrInfo ;
  485.             TQ3Boolean            isText ;
  486.             
  487.             isText = (theReply.sfType == 'TEXT') ;
  488.             
  489.             if ((result = FSpOpenDF(&theReply.sfFile, fsRdWrPerm, &refNum)) != noErr)
  490.                 return ;
  491.                 
  492.             theDocument->fRefNum = refNum;
  493.             
  494.             ReadDocumentFile( theDocument, isText ) ;
  495.             AdjustCamera(theDocument,
  496.                 theDocument->geometriesOffscreen->portRect.right - theDocument->geometriesOffscreen->portRect.left,
  497.                 theDocument->geometriesOffscreen->portRect.bottom - theDocument->geometriesOffscreen->portRect.top);
  498.         } 
  499.     }
  500. #endif
  501.  
  502. }
  503.  
  504.  
  505. Boolean DoSaveAsDocument(DocumentPtr theDocument)
  506. {    short                theResult;
  507.     Str255                thePrompt, theName;
  508.     StandardFileReply    theReply;
  509.  
  510.     if (! theDocument)
  511.         return(false);
  512.  
  513.     GetIndString(thePrompt, FileStringsID, slSavePromptIndex);
  514.     GetWTitle(theDocument->theWindow, theName);
  515.     StandardPutFile( (ConstStr255Param) &thePrompt, (ConstStr255Param) &theName, &theReply);
  516.  
  517.     if (theReply.sfGood) {
  518.         if (!theReply.sfReplacing) {
  519.             if ((theResult = FSpCreate(&theReply.sfFile, FileCreator, FileType, theReply.sfScript)) != noErr) {
  520.                 SysBeep(1);
  521.                 return(false);
  522.             }
  523.         }
  524.         if (theDocument->fRefNum) {
  525.             theResult = FSClose(theDocument->fRefNum);
  526.         }
  527.         if ((theResult = FSpOpenDF(&theReply.sfFile, fsRdWrPerm, &theDocument->fRefNum)) != noErr) {
  528.             SysBeep(1);
  529.             return(false);
  530.         }
  531.  
  532.         if ((theResult = WriteDocumentFile(theDocument)) != noErr) {
  533.             SysBeep(1);
  534.             return(false);
  535.         }
  536.  
  537.         SetWTitle(theDocument->theWindow, theReply.sfFile.name);
  538.         theDocument->dirty = false;
  539.  
  540.     } else {
  541.         return(false);
  542.     }
  543.     return(true);
  544. }
  545.  
  546.  
  547. Boolean DidSaveDocument(DocumentPtr theDocument)
  548. {
  549.  
  550.     if ( theDocument == nil )
  551.         return(false);
  552.  
  553.     if (theDocument->fRefNum) {
  554.         if (WriteDocumentFile(theDocument)) {
  555.             SysBeep(1);
  556.             return(false);
  557.         } else {
  558.             theDocument->dirty = false;
  559.         }
  560.         return(true);
  561.     } else {
  562.         return(DoSaveAsDocument(theDocument));
  563.     }
  564. }
  565.  
  566.  
  567. void DoRevertDocument(DocumentPtr theDocument)
  568.  
  569. {    Str255        theName;
  570.  
  571.     if (! theDocument)
  572.         return;
  573.  
  574.     if (theDocument->fRefNum) {
  575.         GetWTitle(theDocument->theWindow, theName);
  576.         ParamText( (ConstStr255Param) &theName, (ConstStr255Param) "", (ConstStr255Param) "", (ConstStr255Param) "");
  577.         if (Alert(idRevertALRT, 0L) == 1) {
  578.             FInfo                fndrInfo ;
  579.         
  580.             // we assume the FSSpec in the document is valid, get the file information
  581.             // we need to know the file type
  582.             
  583.             FSpGetFInfo( &theDocument->theFileSpec, &fndrInfo ) ;
  584.             
  585.             // pull out the file type
  586.             
  587.             ReadDocumentFile(theDocument, (fndrInfo.fdType == 'TEXT')) ;
  588.         }
  589.     }
  590. }
  591.  
  592.  
  593.